
macro(collect_source_files out_list)
  file(GLOB_RECURSE ${out_list}
    RELATIVE ${CMAKE_CURRENT_LIST_DIR}
    *.h *.cc)

  foreach(src ${${out_list}})
    get_filename_component(fpath ${src} PATH)
    if(fpath)
      string(REPLACE "/" "\\\\" group ${fpath})
      source_group(${group} FILES ${src})
    else(fpath)
      source_group("src" FILES ${src})
    endif(fpath)
  endforeach(src ${${out_list}})
endmacro(collect_source_files out_list)

macro(add_precompiled_header source_files pch)
  string(TOUPPER ${CMAKE_BUILD_TYPE} bt)
  add_custom_command(OUTPUT ${pch}.gch
    COMMAND ${CMAKE_CXX_COMPILER} 
            -std=c++0x ${CMAKE_CXX_FLAGS_${bt}} ${pch} -o ${pch}.gch
    IMPLICIT_DEPENDS CXX ${pch}
    VERBATIM
    )

  set_property(SOURCE ${${source_files}}
    APPEND PROPERTY OBJECT_DEPENDS
    ${pch}.gch
    )
endmacro(add_precompiled_header source_files)

macro(_add_with_pch type target source_files)
  if(${ARGC} EQUAL 4)
    set(pch ${ARGV3})
  else(${ARGC} EQUAL 4)
    set(pch ${CMAKE_CURRENT_LIST_DIR}/precompiled_header.h)
  endif(${ARGC} EQUAL 4)

  add_precompiled_header(${source_files} ${pch})

  if("executable" MATCHES ${type})
    add_executable(${target} ${${source_files}})
  elseif("archive" MATCHES ${type})
    add_library(${target} STATIC ${${source_files}})
  elseif("library" MATCHES ${type})
    add_library(${target} SHARED ${${source_files}})
  else("executable" MATCHES ${type})
    message(FATAL_ERROR "unsupport type : ${type}")
  endif("executable" MATCHES ${type})

  set_target_properties(${target} PROPERTIES
    COMPILE_FLAGS "-include ${pch} -std=c++0x"
    COMPILE_DEFINITIONS "USE_PRECOMPILED_HEADER")
endmacro(_add_with_pch type target source_files)

macro(add_executable_with_pch target source_files)
  _add_with_pch("executable" ${ARGV})
endmacro(add_executable_with_pch target source_files)

macro(add_archive_with_pch target source_files)
  _add_with_pch("archive" ${ARGV})
endmacro(add_archive_with_pch target source_files)

macro(add_library_with_pch target source_files)
  _add_with_pch("library" ${ARGV})
  set_property(TARGET ${target} APPEND_STRING PROPERTY 
    COMPILE_FLAGS " -fPIC")
endmacro(add_library_with_pch target source_files)

